package org.dolphin.service.misc.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.annotation.Resource;
import org.dolphin.base.bean.DueDatePeriodVO;
import org.dolphin.dao.DueDatePeriodDao;
import org.dolphin.entity.misc.DueDatePeriod;
import org.dolphin.service.misc.DueDatePeriodService;
import org.dolphin.util.Pagination;
import org.dolphin.service.base.UserProfileHelper;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service(value = "dueDatePeriodService")
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class DueDatePeriodServiceImpl implements DueDatePeriodService {
  @Autowired(required = true)
  private DueDatePeriodDao dueDatePeriodDao;
  @Resource(name = "messageResource")
  private MessageSource messageSource;

  @Override
  public Date calculateDueDate(Date date, DueDatePeriod dueDatePeriod) {
    Integer year = dueDatePeriod.getYear();
    Integer month = dueDatePeriod.getMonth();
    Integer week = dueDatePeriod.getWeek();
    Integer day = dueDatePeriod.getDay();
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    if (year > 0) {
      cal.add(Calendar.YEAR, year);
    }
    if (month > 0) {
      cal.add(Calendar.MONTH, month);
    }
    if (week > 0) {
      cal.add(Calendar.WEEK_OF_YEAR, week);
    }
    if (day > 0) {
      cal.add(Calendar.DATE, day);
    }
    Date dueDate = cal.getTime();
    return dueDate;
  }

  @Transactional(readOnly = false)
  @Override
  public void createDueDatePeriod(DueDatePeriod dueDatePeriod) {
    String code = dueDatePeriod.getCode();
    DueDatePeriod period = dueDatePeriodDao.getDueDatePeriod(code);
    if (period != null) {
      Locale locale = UserProfileHelper.getUserLocale();
      String field = messageSource.getMessage("field.due.date.period.code", null, locale);
      String error = messageSource.getMessage("error.not.available", new Object[] {field}, locale);
      throw new IllegalArgumentException(error);
    }
    dueDatePeriodDao.saveDueDatePeriod(dueDatePeriod);
  }

  @Transactional(readOnly = false)
  @Override
  public void deleteDueDatePeriod(DueDatePeriod dueDatePeriod) {
    dueDatePeriodDao.deleteDueDatePeriod(dueDatePeriod);
  }

  @Override
  public List<DueDatePeriodVO> getDueDatePeriods(int page, int rows, List<Order> orders) {
    page = page > 0 ? page : 1;
    int startIndex = Pagination.calculateStartIndex(page, rows);
    List<DueDatePeriodVO> list = dueDatePeriodDao.getDueDatePeriods(startIndex, rows, orders);
    return list;
  }

  @Override
  public Long getDueDatePeriodsCount() {
    Long count = dueDatePeriodDao.getDueDatePeriodsCount();
    return count;
  }
}
